﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections;
using System.IO;
using System.Net;
using System.Text.RegularExpressions;

namespace GetWebInfo
{
    class SharePrice
    {
        /* SharePrice 文件格式
         * ***************************************************************************
         * 2011-06-30,A:22.540
         * 2011-06-31,A:22.550
         * 2011-07-01,A:22.560
         * ***************************************************************************
         * 日期,A股价格
         */
        public SharePrice()
        {
        }

        public SortedList<DateTime, decimal> Prices
        {
            get
            {
                return this._prices;
            }
        }
        private SortedList<DateTime, decimal> _prices = new SortedList<DateTime, decimal>();

        public void Save(string stockCode)
        {
            string _filePath = string.Format(@"{0}\{1}\{2}",
                System.AppDomain.CurrentDomain.BaseDirectory,
                stockCode,
                Const.PriceFileName);

            StreamWriter _sw = new StreamWriter(_filePath);
            foreach (KeyValuePair<DateTime, decimal> kvp in _prices)
            {
                _sw.WriteLine(string.Format("{0},A:{1}",
                        kvp.Key.ToString("yyyy-MM-dd"),
                        kvp.Value));
            }
            
            _sw.Close();
        }

        public static SharePrice Load(string stockCode)
        {
            string _filePath = string.Format(@"{0}\{1}\{2}",
                System.AppDomain.CurrentDomain.BaseDirectory,
                stockCode,
                Const.PriceFileName);

            if (!File.Exists(_filePath))
            {
                return null;
            }

            SharePrice _sp = new SharePrice();
            using (StreamReader sr = new StreamReader(_filePath))
            {
                string line;

                while ((line = sr.ReadLine()) != null)
                {
                    if (line != "")
                    {
                        string[] _strs = line.Split(new char[] { ',', ':' });
                        _sp._prices.Add(DateTime.Parse(_strs[0]), decimal.Parse(_strs[2]));
                    }                    
                }
            }

            return _sp;
        }

        /// <summary>
        /// 解析sina的价格
        /// </summary>
        /// <param name="stockCode"></param>
        /// <param name="startYear"></param>
        /// <param name="endYear"></param>
        /// <param name="isAll">如果为true，则获取全部价格</param>
        public static void Parse(string stockCode, string startYear, string endYear, bool isAll)
        {
            if (stockCode.Length != 6)
            {
                Console.WriteLine("The stockCode is empty!");
                return;
            }

            int _startYear = 0;
            int _endYear = 0;

            WebClient _myWebClient = new WebClient();
            string _myWebInfo1 = "";

            if (isAll)
            {
                string _urlPath = string.Format(Const.PagePath_SinaPrice_all, stockCode);
                if (Const.OnlyTest) _urlPath = @"H:\forge\自动下载程序的需求\exe\600016-test\vMS_MarketHistory";

                try
                {
                    _myWebInfo1 = Encoding.Default.GetString(_myWebClient.DownloadData(_urlPath));
                }
                catch (System.Exception exp)
                {
                    Console.WriteLine(exp.Message);
                }
                _startYear = FindFirstYear(_myWebInfo1);
                _endYear = DateTime.Now.Year;
            }
            else
            {
                if (startYear.Length != 4 ||
                        endYear.Length != 4)
                {
                    Console.WriteLine("输入的年份不正确！");
                    return;
                }
                _startYear = int.Parse(startYear);
                _endYear = int.Parse(endYear);
            }

            Console.WriteLine("Parse the sina pricepage of startYear and endYear : [{0}] - [{1}]", _startYear, _endYear);

            SharePrice _sp = SharePrice.Load(stockCode) ?? new SharePrice();            

            for (int i = _startYear; i <= _endYear; i++)
            {
                for (int j = 1; j <= 4; j++)
                {
                    string _urlPath = string.Format(Const.PagePath_SinaPrice, stockCode, i, j);

                    Console.WriteLine("Parse the sina pricepage of : [{0}]", _urlPath);
                    try
                    {
                        _myWebInfo1 = Encoding.Default.GetString(_myWebClient.DownloadData(_urlPath));
                    }
                    catch (System.Exception exp)
                    {
                        Console.WriteLine(exp.Message);
                    }
                    ParseSinaSharePricePage(_myWebInfo1, _sp);
                }
            }

            _sp.Save(stockCode);
        }

        private static int FindFirstYear(string pageInfo)
        {
            int _year = 0;
            //	<select name="year">
            string[] strs = pageInfo.Split(new string[] { "	<select name=\"year\">" }, StringSplitOptions.RemoveEmptyEntries);
            strs = strs[1].Split(new string[] { "			</select>" }, StringSplitOptions.RemoveEmptyEntries);

/* sina实际代码，方便将来核对
        "\n\t\t\t\t\t<option value=\"2012\" selected>2012</option>\n\t\t\t\t\t<option value=\"2011\" >2011</option>\n\t\t\t\t\t<option value=\"2010\" >2010</option>\n\t\t\t\t\t<option value=\"2009\" >2009</option>\n\t\t\t\t\t<option value=\"2008\" >2008</option>\n\t\t\t\t\t<option value=\"2007\" >2007</option>\n"
*/

            strs = strs[0].Split(new string[] { "\n\t\t\t\t\t" }, StringSplitOptions.RemoveEmptyEntries);
            string _str = strs[strs.Length - 1];
            strs = _str.Split(new string[] { "<option value=\"", "	", "\" >", "</option>" }, StringSplitOptions.RemoveEmptyEntries);
            return int.Parse(strs[0]);
        }

        private static void ParseSinaSharePricePage(string pageInfo, SharePrice sp)
        {
            StringReader sr = new StringReader(pageInfo);

            string _line = string.Empty;
            bool _inSharesTable = false;
            bool _inPrice = false;
            DateTime _dt = DateTime.Now;
            decimal _price = 0;
            int i = 0;

            while ((_line = sr.ReadLine()) != null)
            {

                if (_line.Contains("<table id=\"FundHoldSharesTable\">"))
                    _inSharesTable = true;

                if (_inSharesTable)
                {
                    if (!_inPrice)
                    {
                        _line = _line.Replace("\t", "").Replace(" ", "").Replace("\\r", "").Replace("\\n", "").Replace("</a>", "").Replace("</div></td>", "");
                        Regex _re = new Regex(@"^\d{4}-\d{2}-\d{2}$");
                        if (_re.IsMatch(_line))
                        {
                            _dt = DateTime.Parse(_line);
                            _inPrice = true;
                            continue;
                        }
                    }

                    if (_inPrice)
                    {
                        if (_line.Contains("<td><div align=\"center\">"))
                        {
                            i++;
                            if (i == 3)
                            {
                                _line = _line.Replace("<td>", "").Replace("<div align=\"center\">", "").Replace("</div>", "").Replace("</td>", "");
                                _line = _line.Replace("\t", "").Replace(" ", "").Replace("\\r", "").Replace("\\n", "");
                                _price = decimal.Parse(_line);

                                if (!sp.Prices.ContainsKey(_dt))
                                {
                                    sp.Prices.Add(_dt, _price);
                                }
                                i = 0;
                                _inPrice = false;
                                Console.WriteLine("{0},{1}", _dt, _price);
                            }
                            else
                            {
                                continue;
                            }
                        }
                    }
                }
            }

            sr.Close();
        }
    }
}

